package com.ruoyi.business.processIou.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.bizsys.domain.AccountFlow;
import com.ruoyi.bizsys.domain.LoanIou;
import com.ruoyi.bizsys.domain.LoanOffset;
import com.ruoyi.bizsys.domain.RepaymentOrder;
import com.ruoyi.bizsys.mapper.AccountFlowMapper;
import com.ruoyi.bizsys.mapper.LoanIouMapper;
import com.ruoyi.bizsys.mapper.LoanOffsetMapper;
import com.ruoyi.bizsys.mapper.RepaymentOrderMapper;
import com.ruoyi.bizsys.utils.BizConstants;
import com.ruoyi.bizsys.vo.LoanIouExtVo;
import com.ruoyi.business.processIou.domain.LoanIouChangeRecord;
import com.ruoyi.business.processIou.domain.LoanOffsetChangeRecord;
import com.ruoyi.business.processIou.mapper.ILoanOffsetChangeRecordMapper;
import com.ruoyi.business.processIou.service.ILoanOffsetChangeRecordService;
import com.ruoyi.business.processIou.service.MoninflyFinaceService;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.utils.uuid.IdUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;

/**
 * @author wqg
 * @description
 * @date 2022/3/25
 */
@Service
public class ILoanOffsetChangeRecordImpl extends ServiceImpl<ILoanOffsetChangeRecordMapper, LoanOffsetChangeRecord> implements ILoanOffsetChangeRecordService {

    @Autowired
    ILoanOffsetChangeRecordMapper loanOffsetChangeRecordMapper;
    @Autowired
    LoanOffsetMapper loanOffsetMapper;

    @Autowired
    AccountFlowMapper accountFlowMapper;

    @Autowired
    LoanIouMapper loanIouMapper;

    @Autowired
    MoninflyFinaceService moninflyFinaceService;

    @Autowired
    RepaymentOrderMapper repaymentOrderMapper;

    @Transactional
    public void updateRecordAndinsert(LoanOffsetChangeRecord loanOffsetChangeRecord, LoanOffset loanOffset){
        loanOffsetChangeRecordMapper.updateById(loanOffsetChangeRecord);
        loanOffsetMapper.updateById(loanOffset);
    }

    @Override
    @Transactional
    public void DoInsertLoanOffsetAndRepaymentOrder(LoanIou loanIou, String paymentReference, Date completedOn, BigDecimal amountPaid) {
        //ReduceFee reduceFee = reduceFeeMapper.selectOneBySerialNoAndType(loanSerialNo,ReduceFee.ACTION_TYPE_MONNIFLY_FINANCE);
        loanIou.setNumFinance(1);// 只能有一次回溯
        loanIouMapper.updateById(loanIou);
        RepaymentOrder repaymentOrder = createRepaymentOrder(loanIou, paymentReference, completedOn, amountPaid);
        LoanOffset loanOffset = createLoanOffsetSuccess(completedOn, repaymentOrder);
        // 先删除本借据的账目流水
        updateAccountFlowStateFaild(loanIou);
        // 每一笔回溯都需要判断和处理 变成失效
        // 开始回溯
        moninflyFinaceService.init(loanIou.getLoanSerialNo());

    }
    private void updateAccountFlowStateFaild(LoanIou loanIou) {
        AccountFlow accountFlow = new AccountFlow();
        accountFlow.setCustNo(loanIou.getCustNo());
        accountFlow.setRelativeSerialNo(loanIou.getLoanSerialNo());
        accountFlowMapper.updateByIndex(accountFlow);
    }



    private LoanOffset createLoanOffsetSuccess(Date completedOn, RepaymentOrder repaymentOrder) {
        LoanOffset loanOffset = new LoanOffset();
        loanOffset.setCustNo(repaymentOrder.getCustNo());
        loanOffset.setLoanSerialNo(repaymentOrder.getLoanSerialNo());
        loanOffset.setRepaymentNo(repaymentOrder.getRepaymentNo());
        loanOffset.setActionType(repaymentOrder.getActionType());
        loanOffset.setAmt(repaymentOrder.getRepaymentAmt());
        loanOffset.setPayTime(completedOn);
        loanOffset.setLoanPrincipal(repaymentOrder.getLoanPrincipal());
        loanOffset.setRepaidPrincipal(repaymentOrder.getRepaidPrincipal());
        loanOffset.setServiceFee(repaymentOrder.getServiceFee());
        loanOffset.setRepaidServiceFee(repaymentOrder.getRepaidServiceFee());
        loanOffset.setLoanInterest(repaymentOrder.getLoanInterest());
        loanOffset.setRepaidInterest(repaymentOrder.getRepaidInterest());
        if (repaymentOrder.getLateFee() == null) {
            repaymentOrder.setLateFee(BigDecimal.ZERO);
        }
        if (repaymentOrder.getReduceFee() == null) {
            repaymentOrder.setReduceFee(BigDecimal.ZERO);
        }
        loanOffset.setLateFee(repaymentOrder.getLateFee());// 不需要 wqg沟通过 后期遇到延迟冲账的场景去回溯
        loanOffset.setRepaidLateFee(repaymentOrder.getRepaidLateFee());

        loanOffset.setLoanOffsetStatus(BizConstants.LOAN_OFFSET_STATUS_SUCCESS);
        loanOffset.setState(UserConstants.BUSINESS_NORMAL);
        loanOffsetMapper.insert(loanOffset);
        return loanOffset;
    }

    private RepaymentOrder createRepaymentOrder(LoanIou loanIou, String paymentReference, Date completedOn, BigDecimal amountPaid) {
        RepaymentOrder repaymentOrder = new RepaymentOrder();
        repaymentOrder.setRepaymentNo(IdUtils.reqId());
        repaymentOrder.setCustNo(loanIou.getCustNo());
        repaymentOrder.setLoanSerialNo(loanIou.getLoanSerialNo());

        repaymentOrder.setActionType(RepaymentOrder.ACTION_TYPE_FINANCE);

        // 计算减免金额
        BigDecimal reduceAmt = loanIou.getReduceAmt() == null ? BigDecimal.ZERO : loanIou.getReduceAmt();
        repaymentOrder.setRepaymentAmt(amountPaid.setScale(0, BigDecimal.ROUND_UP));
        repaymentOrder.setReduceFee(reduceAmt);

        repaymentOrder.setLoanPrincipal(loanIou.getLoanPrincipal());
        repaymentOrder.setRepaidPrincipal(loanIou.getRepaidPrincipal());
        repaymentOrder.setServiceFee(loanIou.getServiceFee());
        repaymentOrder.setRepaidServiceFee(loanIou.getRepaidServiceFee());
        repaymentOrder.setLoanInterest(loanIou.getLoanInterest());
        repaymentOrder.setRepaidInterest(loanIou.getRepaidInterest());
        repaymentOrder.setLateFee(loanIou.getLateFee());
        repaymentOrder.setRepaidLateFee(loanIou.getRepaidLateFee());
        repaymentOrder.setRepayStatus(BizConstants.REPAYMENT_ORDER_STATUS_SUCCESS);
        repaymentOrder.setPayTransSerialNo(paymentReference);

        repaymentOrder.setPayTime(completedOn);
        repaymentOrder.setState(UserConstants.BUSINESS_NORMAL);
        Date nowTime = new Date();
        repaymentOrder.setCreateTime(nowTime);
        repaymentOrder.setUpdateTime(nowTime);
        repaymentOrderMapper.insert(repaymentOrder);
        return repaymentOrder;
    }

    @Override
    // @Transactional 外层使用了futrue.get 不能事物
    public void updateAndCreateRecord(LoanOffset loanOffset, BigDecimal lateFeePlus, BigDecimal lateFeePlusAll, LoanIouExtVo loanIou, LoanIou iouBeforeDay) {
        // 记录之前的数据
        LoanOffsetChangeRecord loanOffsetChangeRecordBefor = new LoanOffsetChangeRecord();
        BeanUtils.copyProperties(loanOffset,loanOffsetChangeRecordBefor);
        processProperties(loanOffsetChangeRecordBefor,loanOffset, LoanIouChangeRecord.RECORD_TYPE_BEFOR);
        // loanOffsetChangeRecordMapper.insert(loanOffsetChangeRecordBefor);

        // 记录变更之后的数据
        LoanOffsetChangeRecord loanOffsetChangeRecordAfter = new LoanOffsetChangeRecord();
        processNewOffset(loanOffset,loanIou,lateFeePlus,lateFeePlusAll,iouBeforeDay);
        BeanUtils.copyProperties(loanOffset,loanOffsetChangeRecordAfter);
        processProperties(loanOffsetChangeRecordAfter,loanOffset,LoanIouChangeRecord.RECORD_TYPE_AFTER);
        // loanOffsetChangeRecordMapper.insert(loanOffsetChangeRecordAfter);
        loanOffsetMapper.updateById(loanOffset);
    }

    /**
     * 计算新的数据
     * @param loanOffset
     * @param loanIou
     * @param lateFeePlus
     * @param lateFeePlusAll
     */
    private void processNewOffset(LoanOffset loanOffset, LoanIouExtVo loanIou, BigDecimal lateFeePlus, BigDecimal lateFeePlusAll,LoanIou iouBeforeDay) {
        // 最新的总罚息
        loanOffset.setLateFee(lateFeePlusAll);
        // 上次iou已还罚息
        loanOffset.setRepaidLateFee(iouBeforeDay.getRepaidLateFee());
        // 上次iou已还总利息
        loanOffset.setRepaidInterest(iouBeforeDay.getRepaidInterest());
        // 上次iou已还服务费
        loanOffset.setRepaidServiceFee(iouBeforeDay.getRepaidServiceFee());
        // 上次iou已还本金
        loanOffset.setRepaidPrincipal(iouBeforeDay.getRepaidPrincipal());
        loanOffset.setReduceAmt(BigDecimal.ZERO);//正常流程下不需要这个数据
        loanOffset.setOffsetLateFee(loanIou.getOffsetLateFee());
        loanOffset.setOffsetServiceFee(loanIou.getOffsetServiceFee());
        loanOffset.setOffsetInterest(loanIou.getOffsetInterest());
        loanOffset.setOffsetPrincipal(loanIou.getOffsetPrincipal());
    }

    /**
     * 处理对象参数
     * @param loanOffsetChangeRecord
     * @param loanOffset
     * @param recordType
     */
    private void processProperties(LoanOffsetChangeRecord loanOffsetChangeRecord, LoanOffset loanOffset, int recordType) {
        loanOffsetChangeRecord.setId(null);
        loanOffsetChangeRecord.setOffsetId(loanOffset.getId());
        loanOffsetChangeRecord.setRecordType(recordType);
        loanOffsetChangeRecord.setRecordTime(new Date());
    }
}
